<template>
    <table class="dragger-table">
        <thead>
            <tr class="head">
                <th v-for="column in columns" :key="column.prop">
                    {{ column.label }}
                </th>
            </tr>
        </thead>
        <draggable tag="tbody" v-model="draggerData" v-bind="dragOptions" @update="onDraggerUpdate" @end="onDraggerEnd">
            <draggableTableRow v-for="(row, rowindex) in draggerData" :row="row" :key="rowindex">
                <template slot-scope="scope">
                    <slot :scope="scope"></slot>
                </template>
            </draggableTableRow>
        </draggable>
    </table>
  </template>
  
  <script>
  import draggable from 'vuedraggable';
  import draggableTableRow from './draggableTableRow';
  import draggableTableColumn from './draggableTableColumn';
  
  export default {
    name: 'DraggableTable',
    components: {
      draggable,
      draggableTableRow,
      draggableTableColumn
    },
    props: {
      data: {
        type: Array,
        required: true
      }
    },
    data() {
      return {
        columns: [],
        draggerData: []
      };
    },
    watch: {
        data(value) {
            this.draggerData = value.map(c => c)
            this.$nextTick(() => this.bindingCol())
        }
    },
    computed: {
        dragOptions() {
            return {
                animation: 200,
                disabled: false
            }
        }
    },
    created() {
        // console.log(this.data)
        this.draggerData = this.data.map(c => c)
        this.$nextTick(() => this.bindingCol())
    },
    mounted() {
        this.columns = this.$slots.default
        ? this.$slots.default.filter(vnode => vnode.componentOptions && vnode.componentOptions.tag === 'draggable-table-column')
            .map(vnode => vnode.componentOptions.propsData)
        : [];
    },
    methods: {
        checkScope(slots) {
            if (slots && typeof slots.default === 'function') {
                return true
            }
            return false
        },
        onDraggerEnd() {
            this.bindingCol()
            this.$emit('end', this.draggerData)
        },
        onDraggerUpdate(evt) {
            this.$emit('update', this.draggerData)
        },
        cloneData() {
            return this.data.map(c => c)
        },
        bindingCol() {
            for (let i = 0; i < this.$children.length; i ++) {
                const child = this.$children[i]
                for (let rowIndex = 0; rowIndex < child.$children.length; rowIndex ++) {
                    const row = child.$children[rowIndex]
                    for (let colIndex = 0; colIndex < row.$children.length; colIndex ++) {
                        const col = row.$children[colIndex]
                        const defaultScope = col.$scopedSlots
                        col.scope = {
                            $row: {...row.row},
                            prop: col.prop, 
                            label: col.label,
                            value: row.row[col.prop] || "",
                            $index: rowIndex,
                            $colIndex: colIndex,
                            $scope: this.checkScope(defaultScope)
                        }
                    }
                }
            }
        }
    }
  };
  </script>
  
  <style scoped>
  .dragger-table {
    border-collapse: collapse;
    width: 100%;
  }
.head {
    background-color: #efefef !important;
    padding: 8px 0;
    min-height: 40px;
    line-height: 40px;
    color: black;
    font-weight: 500;
    text-align: left;
}
.head th {
    padding: 0 20px;
}
  </style>
  